package dk.aiszone.lang.messer.autosource;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import dk.aiszone.lang.autosource.generatorobjects.interfaces.GeneratorObject;
import dk.aiszone.lang.autosource.generatorobjects.interfaces.SimpleBlockObject;
import dk.aiszone.lang.messer.autosource.interfaces.AbstractModifiableObject;
import dk.aiszone.lang.messer.autosource.interfaces.ComplexStatement;

/**
 * Representation of a switch-statement.
 * 
 * @author Ais
 */
public class SwitchStatement extends AbstractModifiableObject implements ComplexStatement, SimpleBlockObject {

    private final List<SwitchEntry> entries = new ArrayList<SwitchEntry>();
    private final SimpleBlockObject selector;

    /**
     * Constructor for the <code>SwitchStatement</code>.
     * 
     * @param selector
     *            The selector of the statement (<code>switch(&lt;selector&gt;)</code>)
     * @param row
     *            The line of the <code>ModifialbleStatement</code>.
     * @param column
     *            The column of the <code>ModifiableStatement</code>.
     */
    public SwitchStatement(SimpleBlockObject selector, int row, int column) {
        super(row, column);
        this.selector = selector;
    }

    /**
     * Add antry to the switch-statement
     * 
     * @param label
     *            The label of the entry - if <code>null</code> a default entry is added.
     * @param body
     *            The body of the entry.
     */
    public void addEntry(SimpleBlockObject label, SimpleBlockObject body) {
        entries.add(new SwitchEntry(label, body));
    }

    @Override
    public Object clone() {
        SwitchStatement clone = new SwitchStatement(selector, getRow(), getColumn());
        for (Iterator<SwitchEntry> iterator = entries.iterator(); iterator.hasNext();) {
            clone.entries.add(iterator.next());
        }
        return clone;
    }

    @Override
    public String toJava() {
        StringBuilder sb = new StringBuilder();
        sb.append("switch(").append(selector.toJava()).append(") {\n");
        for (Iterator<SwitchEntry> iterator = entries.iterator(); iterator.hasNext();) {
            SwitchEntry entry = iterator.next();
            if (entry.label == null) {
                sb.append("default:\n");
            } else {
                sb.append("case ").append(entry.label.toJava()).append(":\n");
            }

            sb.append(entry.body.toJava());
        }
        sb.append("}");
        return sb.toString();
    }

    /* pp */static class SwitchEntry extends GeneratorObject {

        /* pp */final SimpleBlockObject body;
        /* pp */final SimpleBlockObject label;

        /* pp */SwitchEntry(SimpleBlockObject label, SimpleBlockObject body) {
            this.label = label;
            this.body = body;
        }
    }

    @Override
    public SimpleBlockObject getChild(int index) {
        return entries.get(index).body;
    }

    @Override
    public int getChildCount() {
        return entries.size();
    }

    @Override
    public int getNumberOfSupportedModifications() {
        return 0;
    }

    @Override
    public void modify(int index) {
        throw new IndexOutOfBoundsException(index + " out of bounds");
    }

    @Override
    public void revert() {

    }
}